import requests
from enums.request_enum import request_method
from urllib import request
from urllib import parse
import http.cookiejar
from utils import captcha_util
from utils import config_util
from lxml import etree
from crawler.login import login
import json
from utils import logging_method as log
import warnings

session = requests.session()
wrong_title = "铁路工程管理平台--登录"


def get_tile(text):
    """
    根据文本获取html页面title
    :param text:
    :return:
    """
    tree = etree.HTML(text)
    if tree is not None:
        return None
    return tree.xpath("//title")[0].text


def request(url, method=request_method.GET, headers=None, data=None):
    """
    请求数据
    :param url:
    :param method:
    :param headers:
    :param data:
    :return:
    """
    log.info("请求url: %s" % url)
    if config_util.has_section("proxy"):
        proxy_dict = {
            "http": config_util.get("proxy", "url"),
            "https": config_util.get("proxy", "url")
        }
        response = session.request(method, url, headers=headers, data=data, proxies=proxy_dict)
        return response
    response = session.request(method, url, headers=headers, data=data)
    return response


def request_retry(url, method=request_method.GET, headers=None, data=None):
    """
    请求数据
    :param url:
    :param method:
    :param headers:
    :param data:
    :return:
    """
    log.info("请求url: %s" % url)
    response = request(url, method, headers=headers, data=data)
    if response.headers.get("Content-Type") == "text/html;charset=UTF-8":
        title = get_tile(response.text)
        if title == wrong_title:
            login()
            response = request(url, method, headers=headers, data=data)
    return response


def get(url, headers=None, data=None):
    """
    get方法请求数据
    :param url:
    :param headers:
    :param data:
    :return:
    """
    return request(url, request_method.GET.name, headers=headers, data=data)


def get_retry(url, headers=None, data=None):
    """
    get方法请求数据
    :param url:
    :param headers:
    :param data:
    :return:
    """
    return request_retry(url, request_method.GET.name, headers=headers, data=data)


def get_retry_std(url, headers=None, data=None):
    """
    get方法请求数据,返回json，只适合 responses 是标准输出的情况
    :param url:
    :param headers:
    :param data:
    :return:
    """
    response = get_retry(url, headers=headers, data=data)
    if response.headers.get("Content-Type") != "text/plain;charset=UTF-8":
        log.error("Content-Type 必须是text/plain;charset=UTF-8")
    if response.status_code != 200:
        log.error("请求异常，状态码：", response.status_code)
    response_body = json.loads(response.text)
    return response_body["result"]


def post(url, headers=None, data=None):
    """
    post方法请求数据
    :param url:
    :param headers:
    :param data:
    :return:
    """
    return request(url, request_method.POST.name, headers=headers, data=data)


def post_retry(url, headers=None, data=None):
    """
    post方法请求数据
    :param url:
    :param headers:
    :param data:
    :return:
    """
    return request_retry(url, request_method.POST.name, headers=headers, data=data)


def login_urllib():
    """
    用urllib登录（放弃使用）
    :return:
    """
    warnings.warn("过时的方法", DeprecationWarning)
    login_url = 'https://sso.r93535.com/login'
    figure = '[{"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"},{"webdriver":false},{"language":"zh-CN"},{"colorDepth":24},{"deviceMemory":8},{"hardwareConcurrency":12},{"screenResolution":[1920,1080]},{"availableScreenResolution":[1920,1050]},{"timezoneOffset":-480},{"timezone":"Asia/Shanghai"},{"sessionStorage":true},{"localStorage":true},{"indexedDb":true},{"addBehavior":false},{"openDatabase":true},{"cpuClass":"not available"},{"platform":"Win32"},{"plugins":[["Chrome PDF Plugin","Portable Document Format",[["application/x-google-chrome-pdf","pdf"]]],["Chrome PDF Viewer","",[["application/pdf","pdf"]]],["Native Client","",[["application/x-nacl",""],["application/x-pnacl",""]]]]},{"canvas":["canvas winding:yes","canvas fp:"]},{"webgl":["","extensions:ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;WEBKIT_EXT_texture_filter_anisotropic;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBKIT_WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBKIT_WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBKIT_WEBGL_lose_context;WEBGL_multi_draw","webgl aliased line width range:[1, 1]","webgl aliased point size range:[1, 1024]","webgl alpha bits:8","webgl antialiasing:yes","webgl blue bits:8","webgl depth bits:24","webgl green bits:8","webgl max anisotropy:16","webgl max combined texture image units:32","webgl max cube map texture size:16384","webgl max fragment uniform vectors:1024","webgl max render buffer size:16384","webgl max texture image units:16","webgl max texture size:16384","webgl max varying vectors:30","webgl max vertex attribs:16","webgl max vertex texture image units:16","webgl max vertex uniform vectors:4096","webgl max viewport dims:[32767, 32767]","webgl red bits:8","webgl renderer:WebKit WebGL","webgl shading language version:WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)","webgl stencil bits:0","webgl vendor:WebKit","webgl version:WebGL 1.0 (OpenGL ES 2.0 Chromium)","webgl unmasked vendor:Google Inc. (AMD)","webgl unmasked renderer:ANGLE (AMD, Radeon 520 Direct3D11 vs_5_0 ps_5_0, D3D11-25.20.15003.5010)","webgl vertex shader high float precision:23","webgl vertex shader high float precision rangeMin:127","webgl vertex shader high float precision rangeMax:127","webgl vertex shader medium float precision:23","webgl vertex shader medium float precision rangeMin:127","webgl vertex shader medium float precision rangeMax:127","webgl vertex shader low float precision:23","webgl vertex shader low float precision rangeMin:127","webgl vertex shader low float precision rangeMax:127","webgl fragment shader high float precision:23","webgl fragment shader high float precision rangeMin:127","webgl fragment shader high float precision rangeMax:127","webgl fragment shader medium float precision:23","webgl fragment shader medium float precision rangeMin:127","webgl fragment shader medium float precision rangeMax:127","webgl fragment shader low float precision:23","webgl fragment shader low float precision rangeMin:127","webgl fragment shader low float precision rangeMax:127","webgl vertex shader high int precision:0","webgl vertex shader high int precision rangeMin:31","webgl vertex shader high int precision rangeMax:30","webgl vertex shader medium int precision:0","webgl vertex shader medium int precision rangeMin:31","webgl vertex shader medium int precision rangeMax:30","webgl vertex shader low int precision:0","webgl vertex shader low int precision rangeMin:31","webgl vertex shader low int precision rangeMax:30","webgl fragment shader high int precision:0","webgl fragment shader high int precision rangeMin:31","webgl fragment shader high int precision rangeMax:30","webgl fragment shader medium int precision:0","webgl fragment shader medium int precision rangeMin:31","webgl fragment shader medium int precision rangeMax:30","webgl fragment shader low int precision:0","webgl fragment shader low int precision rangeMin:31","webgl fragment shader low int precision rangeMax:30"]},{"webglVendorAndRenderer":"Google Inc. (AMD)~ANGLE (AMD, Radeon 520 Direct3D11 vs_5_0 ps_5_0, D3D11-25.20.15003.5010)"},{"adBlock":false},{"hasLiedLanguages":false},{"hasLiedResolution":false},{"hasLiedOs":false},{"hasLiedBrowser":false},{"touchSupport":[0,false,false]},{"fonts":["Arial","Arial Black","Arial Narrow","Book Antiqua","Bookman Old Style","Calibri","Cambria","Cambria Math","Century","Century Gothic","Century Schoolbook","Comic Sans MS","Consolas","Courier","Courier New","Georgia","Helvetica","Impact","Lucida Bright","Lucida Calligraphy","Lucida Console","Lucida Fax","Lucida Handwriting","Lucida Sans","Lucida Sans Typewriter","Lucida Sans Unicode","Microsoft Sans Serif","Monotype Corsiva","MS Gothic","MS PGothic","MS Reference Sans Serif","MS Sans Serif","MS Serif","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Segoe UI Light","Segoe UI Semibold","Segoe UI Symbol","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3"]},{"audio":"124.04347527516074"},{"fingure":"3d5684344ff5380a9f4651a7ac0e4035"}]'
    username = 'lNutPzcUPtIeSV1JGGbb7Q=='
    password = 'ONqIfQX7zTbTqtlKbSv6kg=='
    imgId = 'cztl-web-captcha'
    code = captcha_util.get_captcha_val()
    # 设置一个cookie处理器，它负责从服务器下载cookie到本地，并且在发送请求时带上本地的cookie
    cj = http.cookiejar.CookieJar()
    cookie_support = request.HTTPCookieProcessor(cj)
    opener = request.build_opener(cookie_support, request.HTTPHandler)

    request.install_opener(opener)
    raw_data = {"figure": figure, "username": username, "password": password, "imgId": imgId, "code": code}
    post_data = parse.urlencode(raw_data).encode('utf-8')
    cookie = input("输入cookie：")
    headers = {"Cookie": cookie}
    req = request.Request(url=login_url, data=post_data, method='POST')
    # 打开登录主页面（目的是从页面下载cookie，这样我们在再送post数据时就有cookie了，否则发送不成功）
    response = request.urlopen(req)
    if response.status != 200:
        print("请求失败，错误码：", response.status)
    # 解析cookie
    cookie_text = ''
    for item in cj:
        cookie_text = cookie_text + item.name + '=' + item.value + '&'
    cookie_text = cookie_text[0:-1]
    login_page = open("../html/login.html", "wb")
    login_page.write(response.read())
    login_page.close()
    print("登陆请求Cookie：", cookie_text)

